package com.shihb.chapter04collection

import scala.collection.mutable

/**
 * Description:散列表，数组+链表
 * 可变和不可变，通常用可变Map
 *
 * @author shihb
 * @date 2020/9/29 15:03
 */
object Demo05Map {
  def main(args: Array[String]): Unit = {
    test4
  }

  // 不可变的，默认的
  def test: Unit = {
    /*
    key value类型时Any
    在Map的底层，每对key-value时Tuple2
    不可变是有序的
     */
    val map = Map("a" -> 10, "b" -> 30.3)
    println(map)

  }

  // 构建可变的映射
  def test1: Unit = {
    val map: mutable.Map[String, Double] = mutable.Map("a" -> 10, "b" -> 30.3)
    println(map)
    //创建空的映射
    val map1 = new mutable.HashMap[String, Int]()
    println(map1)
    //通过对偶元组来创建
    val map2: mutable.Map[String, Int] = mutable.Map(("a", 1), ("b", 2))
    println(map2)
  }

  // map的取值
  def test2: Unit = {
    //总结:
    //如果我们确定map有值，就用map(key),效率最高
    //不确定有key,而且有不同的业务逻辑使用map.contains()
    //如果只是简单的需要得到一个值map.getOrElse


    val map: mutable.Map[String, Double] = mutable.Map("a" -> 10, "b" -> 30.3)
    // 如果Key存在,返回对应值
    println(map("a"))
    // 如果Key不存在,抛出异常
    //    println(map(""))
    // 方式二:检查key是否存在,再取
    if (map.contains("a")) println(map("a")) else println("不存在")
    // 方式三:map.get("a").get
    // map.get(key) 不存在 返回null
    // 存在返回Some,Some.get就可以取出值
    println(map.get("a").get)
    //    map.get("a").get //抛出异常
    //    方法四：key存在返回值，不存在返回默认值，推荐用法
    println(map.getOrElse("c", "不存在"))
  }


  //修改,添加和删除
  def test3: Unit ={
//    不可变不能添加删除，也不能修改
    val map: mutable.Map[String, Double] = mutable.Map("a" -> 10, "b" -> 30.3)
    // 方式一:如果有key就更新，没有就新增
    map("c")=20
    println(map("c"))
    map("c")=30
    println(map("c"))
    // 方式二：新加存在的就是更新
    map+=("c"->40,"e"->50)
    println(map)
    // 扁平化的加上一个map
    val map2: mutable.Map[String, Double] = mutable.Map("shb" -> 30)
    map2++=map
    println(map2)

    // 删除,key不存在也没事
    map-=("a","d") //不能写成map=map-("a","d")
    println(map)


  }

  // map的遍历
  def test4: Unit ={
    val map: mutable.Map[String, Any] = mutable.Map(("a", 1), ("b", "北京"), ("c", 3.0))
    println("=======方式一:k v=======")
    for((k,v)<- map) println(s"$k map to $v")
    //模式的变形 只会输出key为"a"的值,只能时一个值比较局限
    for(("a",v)<- map) println(s"only need key a -> $v")
    //守卫更加灵活
    for((k,v)<- map if v.isInstanceOf[String] ) println(s"only need value is String $k -> $v")

    println("=======方式二:keys=======")
    for(k<-map.keys) println(k+" map to " +map(k))
    println("=======方式三:values=======")
    for(v<-map.values) println("only "+v)
    println("=======方式四:元组=======")
    for(v<-map) println(v._1 +" map to "+v._2)

  }

}
